package com.danco.training.zaneuskaya.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.springframework.beans.factory.annotation.Required;

/**
 * @author Zaneuskaya Aliaksandra
 *
 */
@Entity
@Table(name = "user")
public class User implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2339969733079299428L;

	@Id
	@GeneratedValue
	@Column(name = "user_id")
	private Integer userId;

	@Column(name = "online")
	private boolean online;

	@OneToOne
	@JoinColumn(name = "account_fk", referencedColumnName = "account_id")
	private Account account;

	@Column(name = "first_name")
	private String firstName;

	@Column(name = "last_name")
	private String lastName;

	@Column(name = "gender")
	@Enumerated(EnumType.STRING)
	private Gender gender;

	@Column(name = "birth_day")
	@Temporal(value = TemporalType.DATE)
	private Date birthdayDate;

	@Column(name = "phone")
	private String phone;

	@Column(name = "website")
	private String webSite;

	@Column(name = "address")
	private String address;

	@Column(name = "status")
	private String status;

	@Column(name = "marital_state")
	@Enumerated(value = EnumType.STRING)
	private MaritalState maritalState;

	@ManyToOne
	@JoinColumn(name = "country_fk", referencedColumnName = "country_id")
	private Country userCountry;

	@ManyToOne
	@JoinColumn(name = "city_fk", referencedColumnName = "city_id")
	private City userCity;

	@OneToMany(fetch = FetchType.LAZY)
	@JoinColumn(name = "user_fk")
	private Set<Education> educations = new HashSet<Education>();

	@OneToMany(fetch = FetchType.LAZY)
	@JoinColumn(name = "user_fk")
	private Set<Job> jobs = new HashSet<Job>();

	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "user_interest", joinColumns = { @JoinColumn(name = "user_fk") }, inverseJoinColumns = { @JoinColumn(name = "interest_fk") })
	private Set<Interest> interests = new HashSet<Interest>();

	@ManyToMany(mappedBy = "members", fetch = FetchType.LAZY)
	private Set<Forum> forums = new HashSet<Forum>();

	@ManyToMany(mappedBy = "participants")
	private Set<Event> events = new HashSet<Event>();

	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "friendship", joinColumns = @JoinColumn(name = "request_sender", unique = true), inverseJoinColumns = @JoinColumn(name = "request_recepient", unique = true))
	private Set<User> friends = new HashSet<User>();

	@ManyToMany(mappedBy = "friends", fetch = FetchType.LAZY)
	private Set<User> friendOf = new HashSet<User>();

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public boolean isOnline() {
		return online;
	}

	public void setOnline(boolean online) {
		this.online = online;
	}

	public Account getAccount() {
		return account;
	}

	@Required
	public void setAccount(Account account) {
		this.account = account;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Gender getGender() {
		return gender;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	public Date getBirthdayDate() {
		return birthdayDate;
	}

	public void setBirthdayDate(Date birthdayDate) {
		this.birthdayDate = birthdayDate;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getWebSite() {
		return webSite;
	}

	public void setWebSite(String webSite) {
		this.webSite = webSite;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public MaritalState getMaritalState() {
		return maritalState;
	}

	public void setMaritalState(MaritalState maritalState) {
		this.maritalState = maritalState;
	}

	public Country getUserCountry() {
		return userCountry;
	}

	public void setUserCountry(Country userCountry) {
		this.userCountry = userCountry;
	}

	public City getUserCity() {
		return userCity;
	}

	public void setUserCity(City userCity) {
		this.userCity = userCity;
	}

	public Set<Education> getEducations() {
		return educations;
	}

	public void setEducations(Set<Education> educations) {
		this.educations = educations;
	}

	public Set<Job> getJobs() {
		return jobs;
	}

	public void setJobs(Set<Job> jobs) {
		this.jobs = jobs;
	}

	public Set<Interest> getInterests() {
		return interests;
	}

	public void setInterests(Set<Interest> interests) {
		this.interests = interests;
	}

	public Set<Forum> getForums() {
		return forums;
	}

	public void setForums(Set<Forum> forums) {
		this.forums = forums;
	}

	public Set<Event> getEvents() {
		return events;
	}

	public void setEvents(Set<Event> events) {
		this.events = events;
	}

	public Set<User> getFriends() {
		return friends;
	}

	public void setFriends(Set<User> friends) {
		this.friends = friends;
	}

	public Set<User> getFriendOf() {
		return friendOf;
	}

	public void setFriendOf(Set<User> friendOf) {
		this.friendOf = friendOf;
	}

	@Override
	public int hashCode() {
		return getUserId();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof User) {
			User other = (User) obj;
			return other.getUserId() == userId;
		}
		return false;
	}

}
